package com.hirsi.module.department.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hirsi.core.expand.TreeNode;
import com.hirsi.module.department.convert.DepartmentConvert;
import com.hirsi.module.department.entity.Department;
import com.hirsi.module.department.mapper.DepartmentMapper;
import com.hirsi.module.department.service.DepartmentService;
import com.hirsi.module.department.vo.EditDepartmentVo;
import com.hirsi.module.department.vo.param.MoveDepartmentParam;
import com.hirsi.module.department.vo.param.RemoveMemberParam;
import com.hirsi.module.department.vo.result.DepartmentTreeResult;
import com.hirsi.module.manager.entity.RManagerDepartment;
import com.hirsi.module.manager.service.RManagerDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author Hirsi
 * @since 2024-03-11
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {

    @Autowired
    private RManagerDepartmentService managerDepartmentService;

    @Override
    public List<DepartmentTreeResult> tree() {
        List<DepartmentTreeResult> results = getBaseMapper().selectDepartmentTreeResult();
        return TreeNode.toTreeList(results);
    }

    @Override
    public EditDepartmentVo edit(Integer id) {
        Department department = lambdaQuery().eq(Department::getId, id)
                .select(Department::getId, Department::getPid, Department::getName).one();
        if (department == null) throw new RuntimeException("部门不存在");
        return DepartmentConvert.INSTANCE.departmentToEditDepartment(department);
    }

    @Override
    public void save(EditDepartmentVo vo) {
        Department department = DepartmentConvert.INSTANCE.editDepartmentVoToDepartment(vo);
        if (department.getId() == null) {
            //部门不存在，需要生成sortNum排序码
            int sortNum = 0;
            Department maxSortNumDepartment = lambdaQuery().eq(Department::getPid, department.getPid())
                    .select(Department::getSortNum).orderByDesc(Department::getSortNum)
                    .last("limit 1").one();
            if (maxSortNumDepartment != null) sortNum = maxSortNumDepartment.getSortNum() + 1;
            department.setSortNum(sortNum);
            department.insert();
        }
        if (department.getPid() != null) {
            Department parentDepartment = lambdaQuery().eq(Department::getId, department.getPid())
                    .select(Department::getIdSplice, Department::getNameSplice).one();
            if (parentDepartment != null) {
                department.setIdSplice(String.format("%s-%s", parentDepartment.getIdSplice(), department.getId()))
                        .setNameSplice(String.format("%s-%s", parentDepartment.getNameSplice(), department.getName()));
            }
        }
        department.updateById();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void move(MoveDepartmentParam param) {
        Department before = lambdaQuery().eq(Department::getId, param.getBeforeId())
                .select(Department::getId, Department::getSortNum, Department::getPid).one();
        if (before == null) throw new RuntimeException("部门不存在");
        Department after = lambdaQuery().eq(Department::getId, param.getAfterId())
                .select(Department::getId, Department::getSortNum, Department::getPid).one();
        if (after == null) throw new RuntimeException("部门不存在");
        if (!before.getPid().equals(after.getPid())) throw new RuntimeException("不同级别的部门无法交换位置");
        int beforeSortNum = before.getSortNum();
        int afterSortNum = after.getSortNum();
        before.setSortNum(afterSortNum).updateById();
        after.setSortNum(beforeSortNum).updateById();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<Integer> ids) {
        removeByIds(ids);
        //删除管理员部门中间表
        managerDepartmentService.lambdaUpdate()
                .in(RManagerDepartment::getDepartmentId, ids)
                .remove();
    }

    @Override
    public void removeMember(RemoveMemberParam param) {
        managerDepartmentService.lambdaUpdate()
                .eq(RManagerDepartment::getDepartmentId, param.getId())
                .in(RManagerDepartment::getManagerId, param.getManagerIds())
                .remove();
    }
}
